<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8">
    <title>挤压多边形以及辉光效果添加</title>
    <style>
        body {
            margin: 0;
            overflow: hidden;
        }

        .tccDraw {
            width: 100%;
            height: 600px;
        }
    </style>
    <script src="js/three.js"></script>
    <script src="js/OrbitControls.js"></script>
    <script src="js/stats.min.js"></script>
    <script src="js/OBJLoader.js"></script>
    <script src="js/postprocessing/CopyShader.js"></script>
    <script src="js/postprocessing/EffectComposer.js"></script>
    <script src="js/postprocessing/FXAAShader.js"></script>
    <script src="js/postprocessing/ShaderPass.js"></script>
    <script src="js/postprocessing/RenderPass.js"></script>
    <script src="js/postprocessing/OutlinePass.js"></script>
</head>

<body>
    <div id="tccDraw" class="tccDraw">
    </div>
    <script>
        let scene, camera, renderer, labelRenderer, controls, showDiv, directionalLight, mesh, stats;
        let composer,renderPass,outlinePass,effectFXAA;  // 辉光使用变量
        //初始化射线位置
        var pick = {
            x: -10000,
            y: -10000
        }
        /* 场景 */
        function initScene() {
            showDiv = document.getElementById("tccDraw");
            scene = new THREE.Scene();
            let axesHelper = new THREE.AxesHelper(500);
            scene.add(axesHelper);
        }
        /* 相机 */
        function initCamera() {
            //透视相机
            camera = new THREE.PerspectiveCamera(45, showDiv.clientWidth / showDiv.clientHeight, 10, 15000);
            camera.position.set(0, 500, 350);
            camera.lookAt(new THREE.Vector3(0, 0, 0));
        }

        /* 渲染器 */
        function initRender() {
            renderer = new THREE.WebGLRenderer({
                antialias: true
            });
            renderer.setSize(showDiv.clientWidth, showDiv.clientHeight);
            showDiv.appendChild(renderer.domElement);
        }

        /* 灯光 */
        function initLight() {
            let ambientLight = new THREE.AmbientLight(0xCCCCCC);
            scene.add(ambientLight);
            directionalLight = new THREE.DirectionalLight(0x585858);
            directionalLight.position.set(0, 3500, 0);
            scene.add(directionalLight);
        }

        /* 控制器 */
        function initControls() {
            controls = new THREE.OrbitControls(camera, showDiv);
        }

        /* 初始化性能插件status */
        function initStats() {
            stats = new Stats();
            document.body.appendChild(stats.dom);
        }

        /* 生成多边几何体的点 */
        function createExtrudeGeometry(points) {
            var shape = new THREE.Shape(points);
            var options = {
                depth: 10
            }
            var ExtrudeGeometry = new THREE.ExtrudeGeometry(shape, options);
            var mater = new THREE.MeshBasicMaterial({
                color: 0xff0354,
            });
            mesh = new THREE.Mesh(ExtrudeGeometry, mater);
            scene.add(mesh);
        }

        /* 点击的几何体添加辉光的效果 */
        function outlineObj(obj){
            console.log(obj);
            initoutline(obj);
            var objs = [];
            objs.push(obj);
            composer.addPass(renderPass);
            outlinePass.selectedObjects = objs;
            outlinePass.edgeStrength = 10.0 // 边框的亮度
            outlinePass.edgeGlow = 1// 光晕[0,1]
            outlinePass.usePatternTexture = true // 是否使用父级的材质
            outlinePass.edgeThickness = 10.0 // 边框宽度
            outlinePass.downSampleRatio = 1 // 边框弯曲度
            outlinePass.pulsePeriod = 5 // 呼吸闪烁的速度
            outlinePass.visibleEdgeColor.set(parseInt(0xffffff)) // 呼吸显示的颜色
            outlinePass.hiddenEdgeColor = new THREE.Color(0, 0, 0) // 呼吸消失的颜色
            outlinePass.clear = true
            composer.addPass(outlinePass)
            effectFXAA.uniforms.resolution.value.set(1 / window.innerWidth, 1 / window.innerHeight)
            effectFXAA.renderToScreen = true
            composer.addPass(effectFXAA)
        }

        /* 初始化辉光组件 */
        function initoutline(obj){
            composer = new THREE.EffectComposer(renderer);
            renderPass = new THREE.RenderPass(scene,camera);
            outlinePass = new THREE.OutlinePass(new THREE.Vector2(window.innerWidth, window.innerHeight),scene,camera,obj);
            effectFXAA = new THREE.ShaderPass(THREE.FXAAShader);
        }
        /* 创建多个几何体 */
        function manyExtrudeGeometry() {
            var points1 = [
                new THREE.Vector2(-22, 30),
                new THREE.Vector2(-18, 20),
                new THREE.Vector2(-20, 10),
                new THREE.Vector2(-30, 10),
                new THREE.Vector2(-40, 10),
                new THREE.Vector2(-22, 30),
            ]
            createExtrudeGeometry(points1);
            var points1 = [
                new THREE.Vector2(22, 30),
                new THREE.Vector2(18, 20),
                new THREE.Vector2(20, 10),
                new THREE.Vector2(30, 10),
                new THREE.Vector2(40, 10),
                new THREE.Vector2(22, 30),
            ]
            createExtrudeGeometry(points1);
            var points1 = [
                new THREE.Vector2(50, 60),
                new THREE.Vector2(50, 50),
                new THREE.Vector2(33, 44),
                new THREE.Vector2(41, 33),
                new THREE.Vector2(52, 22),
                new THREE.Vector2(22, 40),
            ]
            createExtrudeGeometry(points1);
            var points1 = [
                new THREE.Vector2(100, 150),
                new THREE.Vector2(120, 103),
                new THREE.Vector2(140, 196),
                new THREE.Vector2(170, 133),
                new THREE.Vector2(150, 166),
                new THREE.Vector2(180, 75),
            ]
            createExtrudeGeometry(points1);

        }
        /* 通过射线获取点击的对象 */
        function getPickPosition(event) {
            console.log("触发拾取对象的方法");
            var width = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth;
            var height = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight
            pick.x = (event.offsetX / width) * 2 - 1;
            pick.y = (event.offsetY / height) * -2 + 1;
            console.log(event.offsetX);
            console.log(event.offsetY);
            console.log("w:" + width + "h:" + height);
            console.log("x=" + pick.x + "   y=" + pick.y);
            var Objects = null;
            var raycaster = new THREE.Raycaster();
            raycaster.setFromCamera(pick, camera);//根据鼠标屏幕上的位置，和场景中的相机去计算射线位置
            intersectedObjects = raycaster.intersectObjects(scene.children);//返回的是个数组，里面包含所有拾取到的对象
            console.log(intersectedObjects);
            if (intersectedObjects.length > 0) {
                for (var i = 0; i < intersectedObjects.length; i++) {
                    //intersectedObjects[i].object.material.color.set(0xffffff);
                    outlineObj(intersectedObjects[i].object);
                }
            }
        }

        window.addEventListener("click", getPickPosition);
        initScene();
        initCamera();
        initLight();
        initControls();
        initRender();
        initStats();
        manyExtrudeGeometry();
        animate();
        /* 循环渲染 */
        function animate() {
            stats.update();
            renderer.render(scene, camera);
            if(composer){
                composer.render();
            }
            requestAnimationFrame(animate);
        }
    </script>
</body>

</html>